package com.xu.sso.server.controller;

import com.xu.sso.core.config.SSOConfig;
import com.xu.sso.core.enums.ErrorMessage;
import com.xu.sso.core.exception.SSOException;
import com.xu.sso.core.model.BaseResponse;
import com.xu.sso.core.utils.CookiesUtil;
import com.xu.sso.db.model.base.Department;
import com.xu.sso.db.model.base.User;
import com.xu.sso.server.model.request.LoginRequest;
import com.xu.sso.server.model.response.LoginResponse;
import com.xu.sso.server.service.LoginService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

@Controller
@Slf4j
public class IndexController {

    @Autowired
    private LoginService loginService;

    @GetMapping(SSOConfig.LOGIN)
    public String login(Model model, HttpServletRequest request) {
        model.addAttribute(SSOConfig.APP_ID, request.getParameter(SSOConfig.APP_ID));
        return "start";
    }

    @GetMapping(SSOConfig.LOGOUT)
    public String logout(Model model, HttpServletRequest request, HttpServletResponse response) {
        loginService.logout(request, response);
        model.addAttribute("appId", request.getParameter(SSOConfig.APP_ID));
        return "login";
    }

    @RequestMapping("/start")
    public String start(Model model, HttpServletRequest request, HttpServletResponse response) {
        try {
            // check login
            LoginResponse loginResponse = loginService.checkLogin(request);
            if (StringUtils.isNotBlank(loginResponse.getToken())) {
                String redirectUrl = loginResponse.getRedirectUrl();
                if (StringUtils.isNotBlank(redirectUrl)) {
                    model.addAttribute(SSOConfig.TOKEN, loginResponse.getToken());
                    model.addAttribute(SSOConfig.REDIRECT_URL, loginResponse.getRedirectUrl());
                    CookiesUtil.set(response, SSOConfig.TOKEN, loginResponse.getToken());
                    return "end";
                }
                model.addAttribute("errMsg", ErrorMessage.NoRedirectUrl.getErrMsg());
            }
        } catch (SSOException e) {
            log.error(">>>>>>>>>>IndexController.login error===={}", e);
            model.addAttribute("errMsg", e.getMessage());
        }

        model.addAttribute("appId", request.getParameter(SSOConfig.APP_ID));
        return "login";
    }

    @PostMapping("/doLogin")
    public String doLogin(Model model, LoginRequest loginRequest, HttpServletResponse response) {

        try {
            LoginResponse loginResponse = loginService.login(loginRequest);
            if (StringUtils.isNotBlank(loginResponse.getRedirectUrl())) {
                model.addAttribute(SSOConfig.TOKEN, loginResponse.getToken());
                model.addAttribute(SSOConfig.REDIRECT_URL, loginResponse.getRedirectUrl());
                CookiesUtil.set(response, SSOConfig.TOKEN, loginResponse.getToken());
                return "end";
            }
            model.addAttribute("errMsg", ErrorMessage.NoRedirectUrl.getErrMsg());

        } catch (SSOException e) {
            log.error(">>>>>>>>>>IndexController.doLogin error===={}", e);
            model.addAttribute("errMsg", e.getMessage());
        }

        model.addAttribute("appId", loginRequest.getAppId());
        return "login";
    }

    @RequestMapping("/end")
    public String end(String redirectUrl, String token, HttpServletResponse response) {
        String redirectUrlFinal = redirectUrl + "?" + SSOConfig.TOKEN + "=" + token;
        response.addHeader(SSOConfig.TOKEN, token);
        return "redirect:" + redirectUrlFinal;
    }

    @RequestMapping("/toRegister")
    public String toRegister(Model model) {
        List<Department> list = loginService.findAllDepartments();
        model.addAttribute("deps", list);
        return "register";
    }

    @RequestMapping("/toReset")
    public String toReset() {
        return "reset";
    }

    @RequestMapping("/register")
    @ResponseBody
    public BaseResponse register(User user) {
        BaseResponse response = new BaseResponse();
        try {
            response = loginService.register(user);
        } catch (SSOException e) {
            response.setCode(e.getCode());
            response.setMsg(e.getMessage());
        }
        return response;
    }

    @RequestMapping("/reset")
    @ResponseBody
    public BaseResponse reset(String username, String mail) {
        BaseResponse response = new BaseResponse();
        try {
            response = loginService.reset(username, mail);
        } catch (SSOException e) {
            response.setCode(e.getCode());
            response.setMsg(e.getMessage());
        }
        return response;
    }

}
